import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import GUI from "lil-gui";
import { color } from "three/tsl";

/* 
  加载纹理
*/
const textureLoader = new THREE.TextureLoader();
const simpleShadow = textureLoader.load("src/assets/shadow/simpleShadow.jpg");
/**
 * Base
 */
// Debug
const gui = new GUI();

// Scene
const scene = new THREE.Scene();

/**
 * Lights
 */
// Ambient light
const ambientLight = new THREE.AmbientLight(0xffffff, 1);
gui.add(ambientLight, "intensity").min(0).max(3).step(0.001);
scene.add(ambientLight);

// PointLight
// SpotLight
const spotLight = new THREE.SpotLight(0xffffff, 40, 10, Math.PI * 0.3);

spotLight.position.set(0, 2, 2);

scene.add(spotLight);

/**
 * Materials
 */
const material = new THREE.MeshStandardMaterial();
material.roughness = 0.7;
gui.add(material, "metalness").min(0).max(1).step(0.001);
gui.add(material, "roughness").min(0).max(1).step(0.001);

/**
 * Objects
 */
const sphere = new THREE.Mesh(new THREE.SphereGeometry(0.5, 32, 32), material);

const plane = new THREE.Mesh(new THREE.PlaneGeometry(5, 5), material);
plane.rotation.x = -Math.PI * 0.5;
plane.position.y = -0.5;

//开启接收投影阴影
plane.receiveShadow = false;

scene.add(sphere, plane);

/* 
  创建阴影平面
*/
const sphereShadow = new THREE.Mesh(
  new THREE.PlaneGeometry(1.5, 1.5),
  new THREE.MeshBasicMaterial({
    color: 0x000000,
    //alphaMap贴图必须先开启透明
    transparent: true,
    //开启简易阴影贴图
    alphaMap: simpleShadow,
  })
);
//旋转到与球垂直方向垂直
sphereShadow.rotation.x = -Math.PI * 0.5;
//比平面高一点，不要重叠
sphereShadow.position.y = plane.position.y + 0.01;
scene.add(sphereShadow);
/**
 * Sizes
 */
const sizes = {
  width: window.innerWidth,
  height: window.innerHeight,
};

window.addEventListener("resize", () => {
  // Update sizes
  sizes.width = window.innerWidth;
  sizes.height = window.innerHeight;

  // Update camera
  camera.aspect = sizes.width / sizes.height;
  camera.updateProjectionMatrix();

  // Update renderer
  renderer.setSize(sizes.width, sizes.height);
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
});

/**
 * Camera
 */
// Base camera
const camera = new THREE.PerspectiveCamera(
  75,
  sizes.width / sizes.height,
  0.1,
  100
);
camera.position.x = 1;
camera.position.y = 1;
camera.position.z = 2;
scene.add(camera);

/**
 * Renderer
 */
const renderer = new THREE.WebGLRenderer();
renderer.setSize(sizes.width, sizes.height);
renderer.domElement.setAttribute("class", "my-canvas");
document.body.appendChild(renderer.domElement);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));

// Controls
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;

/**
 * Animate
 */
const clock = new THREE.Clock();

const tick = () => {
  const elapsedTime = clock.getElapsedTime();

  //移动球体来测试阴影
  sphere.position.x = Math.cos(elapsedTime) * 1.5;
  sphere.position.z = Math.sin(elapsedTime) * 1.5;
  sphere.position.y = Math.abs(Math.sin(elapsedTime * 3));

  /* 
    由于我们的阴影时个平面，我们可以更新阴影的坐标来追踪球体
  */
  sphereShadow.position.x = sphere.position.x;
  sphereShadow.position.z = sphere.position.z;
  //然后根据求得高度调整阴影清晰度，即平面的不透明度
  sphereShadow.material.opacity = (1 - sphere.position.y) * 0.3;
  // Update controls
  controls.update();

  // Render
  renderer.render(scene, camera);

  // Call tick again on the next frame
  window.requestAnimationFrame(tick);
};

tick();
